package org.judking.CarKeeper.command.EarlyWarning;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.judking.CarKeeper.command.BaseObdCommand;
import org.judking.CarKeeper.command.service.CommandListener;
import org.judking.CarKeeper.service.EarlyWarningService;

public class TroubleDelegation extends CommandListener		{
	private SpeedDetector speedDetector;
	private CoolantTemperatureDetector coolantTemperatureDetector;
	private FuelLevelDetector fuelLevelDetector;
	private IntakeAirTemperatureDetector intakeAirTemperatureDetector;
	private TimeAfterIgnitionDetector timeAfterIgnitionDetector;
	private WarmUpCheck warmUpCheck;
	private Set<SupportDetector> supportDetector;
	
	public TroubleDelegation()		{
		this.speedDetector  = new SpeedDetector();
		this.coolantTemperatureDetector = new CoolantTemperatureDetector();
		EarlyWarningService.register(coolantTemperatureDetector);
		this.fuelLevelDetector = new FuelLevelDetector();
		EarlyWarningService.register(fuelLevelDetector);
		this.intakeAirTemperatureDetector = new IntakeAirTemperatureDetector();
		this.timeAfterIgnitionDetector = new TimeAfterIgnitionDetector();
		this.warmUpCheck = new WarmUpCheck();
		EarlyWarningService.register(warmUpCheck);
		this.supportDetector = new HashSet<TroubleDelegation.SupportDetector>();
	}
	
	@Override
	public void run() {
		for(BaseObdCommand command : commands)			{
			String cmd = command.genCmd();
			if(cmd.equalsIgnoreCase("010d"))		{
				speedDetector.detect(command);
				setSupport(SupportDetector.SPEED);
			}
			else if(cmd.equalsIgnoreCase("0105"))		{
				coolantTemperatureDetector.detect(command);
				setSupport(SupportDetector.COOLANT_TEMP);
			}
			else if(cmd.equalsIgnoreCase("012f"))			{
				fuelLevelDetector.detect(command);
				setSupport(SupportDetector.FUEL_LEVEL);
			}
			else if(cmd.equalsIgnoreCase("010f"))		{
				intakeAirTemperatureDetector.detect(command);
				setSupport(SupportDetector.INTAKE_AIR_TEMP);
			}
			else if(cmd.equalsIgnoreCase("011f"))		{
				timeAfterIgnitionDetector.detect(command);
				setSupport(SupportDetector.TIME_AFTER_IGNITION);
			}
		}
		
		fireWarmUpCheck();
	}
	
	private void fireWarmUpCheck()			{
		if(iSupport(SupportDetector.SPEED) &&
			iSupport(SupportDetector.INTAKE_AIR_TEMP) &&
			iSupport(SupportDetector.TIME_AFTER_IGNITION))				{
			warmUpCheck.check(intakeAirTemperatureDetector, timeAfterIgnitionDetector, speedDetector);
		}
	}
	
	private void setSupport(SupportDetector sd)			{
		supportDetector.add(sd);
	}
	
	/**
	 *test if a specific SupportDetector is supported
	 * @param sd
	 * @return
	 */
	public boolean iSupport(SupportDetector sd)			{
		return supportDetector.contains(sd);
	}
	
	
	
	static enum SupportDetector		{
		SPEED,
		COOLANT_TEMP,
		FUEL_LEVEL,
		INTAKE_AIR_TEMP,
		TIME_AFTER_IGNITION
	}
}
